﻿using Microsoft.Extensions.Caching.Memory;
using OA.Core;
using OA.Core.Helper;
using OA.Model;
using OA.Model.View;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OA.BLL
{
    public class CacheHelper :CBase
    {

        public static List<string> CacheKeys = new List<string>();

        private IMemoryCache _memoryCache;

        public CacheHelper(IMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }

        /// <summary>
        /// 缓存绝对过期时间
        /// </summary>
        ///<param name="key">Cache键值</param>
        ///<param name="value">给Cache[key]赋的值</param>
        ///<param name="minute">minute分钟后绝对过期</param>
        public void CacheInsertAddMinutes(string key, object value, int minute)
        {
            if (value == null) return;
            if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
            _memoryCache.Set(key, value, TimeSpan.FromMinutes(minute));
        }


        /// <summary>
        /// 缓存相对过期，最后一次访问后minute分钟后过期
        /// </summary>
        ///<param name="key">Cache键值</param>
        ///<param name="value">给Cache[key]赋的值</param>
        ///<param name="minute">滑动过期分钟</param>
        public void CacheInsertFromMinutes(string key, object value, int minute)
        {
            if (value == null) return;
            if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
            _memoryCache.Set(key, value, new MemoryCacheEntryOptions()
                    .SetSlidingExpiration(TimeSpan.FromMinutes(minute)));
        }


        /// <summary>
        ///以key键值，把value赋给Cache[key].如果不主动清空，会一直保存在内存中.
        /// </summary>
        ///<param name="key">Cache键值</param>
        ///<param name="value">给Cache[key]赋的值</param>
        public void CacheInsert(string key, object value)
        {
            if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
            _memoryCache.Set(key, value);
        }

        /// <summary>
        ///清除Cache[key]的值
        /// </summary>
        ///<param name="key"></param>
        public void Clear(string key)
        {
            if (CacheKeys.Contains(key)) { CacheKeys.Remove(key); }
            _memoryCache.Remove(key);
        }

        /// <summary>
        ///根据key值，返回Cache[key]的值
        /// </summary>
        ///<param name="key"></param>
        public T GetValue<T>(string key)
        {
            if (_memoryCache.Get(key) == null) return default(T);
            string result = _memoryCache.Get(key).ToString();
            if (string.IsNullOrWhiteSpace(result)) { return default(T); }
            return JsonHelper.DeserializeObj<T>(result);
        }

        public List<T> GetValues<T>(string key)
        {
            if (_memoryCache.Get(key) == null) return null;
            string result = _memoryCache.Get(key).ToString();
            if (string.IsNullOrWhiteSpace(result)) { return null; }
            return JsonHelper.DeserializeList<T>(result);
        }


        public string GetTableTemplate()
        {
            try
            {
                 
                string key = "Config.TableTemplate";
                var result = _memoryCache.Get<string>(key);
                if (result == null)
                {
                    SysConfig config = this.dbContextFactory.DbContext.SysConfig.Where(m => m.Key.ToLower() == "TableTemplate".ToLower()).FirstOrDefault();
                    if (config != null)
                    {
                        _memoryCache.Set(key, config.Content);
                        if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                        return config.Content;
                    }
                }
                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                throw ex;
            }

        }

        public T GetConfig<T>()
        {
            try
            {
                string typeName = typeof(T).Name.ToLower();
                string key = "Config." + typeName;
                var result = _memoryCache.Get<T>(key);
                if (result == null)
                {
                    SysConfig config = this.dbContextFactory.DbContext.SysConfig.Where(m => m.Key.ToLower() == typeName).FirstOrDefault();
                    if (config != null)
                    {
                        T t = JsonHelper.DeserializeObj<T>(config.Content);
                        if (t != null)
                        {
                            _memoryCache.Set(key, t);
                            if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                            return t;
                        }
                    }
                }
                return result;
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
                throw ex;
            }
            
        }
 


        public List<Position> GetPositions()
        {
            string key = "Config.Positions";
            var result = _memoryCache.Get<List<Position>>(key);
            if (result == null || result.Count == 0)
            {
                result=  this.dbContextFactory.DbContext.Position.ToList();
                if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                _memoryCache.Set(key,result);                
            }
            if (result == null) { result = new List<Position>(); }
            return result;
        }

        public List<VPosition> GetVPositions()
        {
            string key = "Config.VPositions";
            var result = _memoryCache.Get<List<VPosition>>(key);
            if (result == null || result.Count == 0)
            {
                result = this.dbContextFactory.DbContext.VPosition.ToList();
                if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                _memoryCache.Set(key, result);
            }
            if (result == null) { result = new List<VPosition>(); }
            return result;
        }

        public List<Department> GetDepartments()
        {
            string key = "Config.Departments";
            var result = _memoryCache.Get<List<Department>>(key);
            if (result == null || result.Count == 0)
            {
                result = this.dbContextFactory.DbContext.Department.ToList();
                if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                _memoryCache.Set(key, result);
            }
            if (result == null) { result = new List<Department>(); }
            return result;
        }

        public void ClearEmployeesCache()
        {
            _memoryCache.Remove("Config.Employees");
        }

        public List<Employee> GetEmployees()
        {
            string key = "Config.Employees";
            var result = _memoryCache.Get<List<Employee>>(key);
            if (result == null || result.Count == 0)
            {
                result = this.dbContextFactory.DbContext.Employee.ToList();
                if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                _memoryCache.Set(key, result);
            }
            if (result == null) { result = new List<Employee>(); }
            return result;
        }

        public List<EmployeePosition> GetEmployeePositions()
        {
            string key = "Config.EmployeePosition";
            var result = _memoryCache.Get<List<EmployeePosition>>(key);
            if (result == null || result.Count == 0)
            {
                result = this.dbContextFactory.DbContext.EmployeePosition.ToList();
                if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                _memoryCache.Set(key, result);
            }
            if (result == null) { result = new List<EmployeePosition>(); }
            return result;
        }


        public List<VEmployeePosition> GetVEmployeePositions()
        {
            string key = "Config.VEmployeePosition";
            var result = _memoryCache.Get<List<VEmployeePosition>>(key);
            if (result == null || result.Count == 0)
            {
                result = this.dbContextFactory.DbContext.VEmployeePosition.ToList();
                if (!CacheKeys.Contains(key)) { CacheKeys.Add(key); }
                _memoryCache.Set(key, result);
            }
            if (result == null) { result = new List<VEmployeePosition>(); }
            return result;
        }


    }
}
